/*
 * @Author: 来自火星的码农 15122322+heyzhi@user.noreply.gitee.com
 * @Date: 2025-07-24 15:36:42
 * @LastEditors: 来自火星的码农 15122322+heyzhi@user.noreply.gitee.com
 * @LastEditTime: 2025-09-11 17:15:46
 * @FilePath: /server/workspace/src/base/iomanager.h
 * @Description: 这是默认设置,请设置`customMade`, 打开koroFileHeader查看配置 进行设置: https://github.com/OBKoro1/koro1FileHeader/wiki/%E9%85%8D%E7%BD%AE
 */
#pragma once
#include"fiber.h"
#include"scheduler.h"
#include"mutex.h" 
#include <cstdint>
#include "timer.h"
namespace Yizhi
{
    class IOManager: public Scheduler,public TimerManager{
        public:
        typedef std::shared_ptr<IOManager> ptr;
        typedef RWMutex RWMutexType;


         /// @brief 
         enum Event{
            NONE=0x0,
            /// @brief read==epollin,表示读事件
            READ=0x1,
            /// @brief wirte==epollout，表示写事件
            WRITE=0x4
        };

        struct FdContext
        {
            /* data */
            typedef Mutex MutexType;

            /// @brief 事件上下文，表示该事件触发后，需要执行的操作
            struct Eventcontext{
                std::function<void ()> cb;//需要执行的回调函数
                Fiber::ptr fiber;//需要执行的任务协程
                Yizhi::Scheduler* m_scheduler;//指定的协程调度器

                void reset();
            };



    

            /// @brief  根据事件类型返回对应需要操作的事件上下文
            Eventcontext& GetEvent(Event event);


            /// @brief 重置事件上下文
            void resetEventcontext(Event event);

            /// @brief 触发事件上下文的任务，并重置上下文内容
            /// @param event 上下文类型
            void triggerEvent(Event event);
          

            Eventcontext Read;//写事件
            Eventcontext Write;//读事件


            int fd=0;//事件描述符

            Event m_events=NONE;//fd关心的事件

            MutexType m_mutex;
        };
        
        
        IOManager(int threads=1,bool user_caller=true,std::string name="");
        
        ~IOManager();


        /// @brief
        void resizeFdcontexts(size_t size);

       /// @brief 重写线程闲置时，需要执行的操作
       void idle() override;

       /// @brief 重写唤醒闲置线程的方法
       void tickle() override;

       /// @brief 重写判断调度是否可以停止的条件
       /// @return 调度器是否可以停止
       bool isStoped() override;


       void onTimerInsertFront() override;
       
       /// @brief 添加需要监听的事件
       /// @param fd 事件句柄
       /// @param  事件类型
       /// @param cb 事件触发后需要执行的操作
       int addEvent(int fd,Event,std::function<void()> cb=nullptr);


       /// @brief 删除epoll中的监听事件
       /// @param fd 
       /// @param  
       /// @return 
       bool delEvent(int fd,Event);


       /// @brief 取消监听事件
       /// @param fd 
       /// @param  
       /// @return 
       bool cancleEvent(int fd,Event);


       /// @brief 取消epoll中的所有事件
       /// @param fd 
       /// @return 
       bool cancleAll(int fd);
        
       bool stopping(uint64_t timeout);
       public:
        static IOManager* GetThis();
       private:
        //epoll句柄
        int m_epfd=0;

        //管道句柄，用于唤醒空闲线程
        int m_tickleFds[2];
        
        //待处理事件的数量
        std::atomic<size_t> m_pendingEventCount={0};

        //socket事件上下文集合
        std::vector<FdContext *> m_FdContexts;

        RWMutexType m_rwmutex;

    };
    
} // namespace Yizhi